/*
 * @(#)HttpServletUtils.java 2017年4月5日 下午2:49:50
 * Copyright 2017 施建波, Inc. All rights reserved. 积木科技
 * PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package com.jnzc.ocr.common.utils;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.jnzc.ocr.common.error.BusinessException;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.SSLContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * <p>File：HttpServletUtils.java</p>
 * <p>Title: </p>
 * <p>Description:</p>
 * <p>Copyright: Copyright (c) 2017年4月5日 下午2:49:50</p>
 * <p>Company: 积木科技</p>
 * @author 施建波
 * @version 1.0
 */
public class HttpServletUtils
{
    private static final Logger logger = LoggerFactory.getLogger(HttpServletUtils.class);
    
    /**
     * 内容输出
     * @param response
     * @param content
     * @author 施建波  2017年4月5日 下午2:50:07
     */
    public static void webOutConent(HttpServletResponse response, String content){
        try {
            response.setContentType("text/html;charset=" + "utf-8");
            BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
            out.write(content.getBytes("utf-8"));
            out.flush();
            out.close();
        } catch (Exception e) {
            logger.error("内容输出异常:" + e.getMessage(), e);
        }
    }
    
    /**
     * 判断是否是ajax请求
     * @param request
     * @return
     * @author 施建波  2017年5月9日 上午11:27:15
     */
    public static boolean isAjax(HttpServletRequest request){
        return "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
    }
    
    /**
     * 获取请求参数
     * @param request
     * @return
     * @author 施建波  2017年4月5日 下午2:54:34
     */
    @SuppressWarnings("rawtypes")
    public static Map<String, String> requestParams(HttpServletRequest request){
        Map<String,String> params = new HashMap<String,String>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            if(StringUtils.isNotBlank(valueStr)){
                params.put(name, valueStr);
            }
        }
        return params;
    }
    
    /**
     * HTTP GET请求
     * @param url   请求地址
     * @return
     * @author 施建波  2017年4月11日 上午10:47:55
     */
    public static JSONObject httpGet(String url){
        try{
            CloseableHttpClient httpClient = getHttpClient(Boolean.FALSE, null, null); 
            HttpGet httpGet = new HttpGet(url);
            HttpResponse response = httpClient.execute(httpGet);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != HttpStatus.SC_OK) {
                throw new Exception(url+" 请求失败");
            }
            String result = EntityUtils.toString(response.getEntity(), "utf-8");
            return JsonUtils.fromJson(result, JSONObject.class);
        }catch(Exception e){
            logger.error(e.getMessage(), e);
            throw new BusinessException("GET请求失败");
        }
    }
    
    public static String httpGetByStr(String url){
        try{
            CloseableHttpClient httpClient = getHttpClient(Boolean.FALSE, null, null); 
            HttpGet httpGet = new HttpGet(url);
            HttpResponse response = httpClient.execute(httpGet);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != HttpStatus.SC_OK) {
                throw new Exception(url+" 请求失败");
            }
            String result = EntityUtils.toString(response.getEntity(), "utf-8");
            return result;
        }catch(Exception e){
            logger.error(e.getMessage(), e);
            throw new BusinessException("GET请求失败");
        }
    }
    
    /**
     * HTTP POST请求
     * @param url   请求地址
     * @param param 请求参数
     * @return
     * @author 施建波  2017年4月11日 上午10:54:17
     */
    public static JSONObject httpPost(String url, Map<String, Object> param){
        try{
            String result = httpPostContent(url, param);
            return JsonUtils.fromJson(result, JSONObject.class);
        }catch(Exception e){
            logger.error(e.getMessage(), e);
            throw new BusinessException("POST请求失败");
        }
    }
    
    public static String httpPostContent(String url, Map<String, Object> param){
        try{
            CloseableHttpClient httpClient = getHttpClient(Boolean.FALSE, null, null); 
            List<BasicNameValuePair> formparams = Lists.newArrayList();
            if(MapUtils.isNotEmpty(param)){
                for(Map.Entry<String, Object> entry:param.entrySet()){
                    Object obj = entry.getValue();
                    if(null != obj){
                        String value = obj.toString();
                        if(StringUtils.isNotBlank(value)){
                            BasicNameValuePair nameValuePair = new BasicNameValuePair(entry.getKey(), value);
                            formparams.add(nameValuePair);
                        }
                    }
                } 
            }
            HttpPost httpPost = new HttpPost(url);
            httpPost.setEntity(new UrlEncodedFormEntity(formparams, "utf-8"));
            HttpResponse response = httpClient.execute(httpPost);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != HttpStatus.SC_OK) {
                throw new Exception(url+" 请求失败");
            }
            String result = EntityUtils.toString(response.getEntity(), "utf-8");
            return result;
        }catch(Exception e){
            logger.error(e.getMessage(), e);
            throw new BusinessException("POST请求失败");
        }
    }
    
    /**
     * HTTP XML POST请求
     * @param url
     * @param xmlParam
     * @return
     * @author 施建波  2017年4月21日 上午11:40:48
     */
    public static String httpXmlPostContent(String url, String xmlParam){
        try{
            CloseableHttpClient httpClient = getHttpClient(Boolean.FALSE, null, null); 
            
            HttpPost httpPost = new HttpPost(url);
            StringEntity xmlEntity = new StringEntity(xmlParam, "utf-8");
            httpPost.setEntity(xmlEntity);
            HttpResponse response = httpClient.execute(httpPost);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != HttpStatus.SC_OK) {
                throw new Exception(url+" 请求失败");
            }
            String result = EntityUtils.toString(response.getEntity(), "utf-8");
            if(StringUtils.isBlank(result)){
                throw new Exception(url+" 请求失败");
            }
            return result;
        }catch(Exception e){
            logger.error(e.getMessage(), e);
            throw new BusinessException("XMLPOST请求失败"); 
        }
    }
    
    public static String httpsXmlPostContent(Boolean isSsl, String certPath, String mchId, String url, String xmlParam){
        try{
            CloseableHttpClient httpClient = getHttpClient(Boolean.TRUE, certPath, mchId); 
            
            HttpPost httpPost = new HttpPost(url);
            StringEntity xmlEntity = new StringEntity(xmlParam, "utf-8");
            httpPost.setEntity(xmlEntity);
            HttpResponse response = httpClient.execute(httpPost);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != HttpStatus.SC_OK) {
                throw new Exception(url+" 请求失败");
            }
            String result = EntityUtils.toString(response.getEntity(), "utf-8");
            if(StringUtils.isBlank(result)){
                throw new Exception(url+" 请求失败");
            }
            return result;
        }catch(Exception e){
            logger.error(e.getMessage(), e);
            throw new BusinessException("XMLPOST请求失败"); 
        }
    }
    
    private static CloseableHttpClient getHttpClient(Boolean isSsl, String certPath, String mchId) throws Exception {
        if(isSsl){
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            //P12文件目录
            FileInputStream instream = new FileInputStream(certPath);
            try {
                keyStore.load(instream, mchId.toCharArray());
            } finally {
                instream.close();
            }
            SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, mchId.toCharArray()).build();
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext);
            return HttpClients.custom().setSSLSocketFactory(sslsf).build();
        }else{
            return HttpClients.createDefault();
        }
    }
    
    /**
     * 获取POST参数
     * @param request
     * @return
     * @throws Exception
     * @author 施建波  2017年4月13日 上午9:46:02
     */
    public static String getRequestPostStr(HttpServletRequest request) throws Exception {
        byte buffer[] = getRequestPostBytes(request);
        String charEncoding = request.getCharacterEncoding();
        if (charEncoding == null) {
            charEncoding = "utf-8";
        }
        return new String(buffer, charEncoding);
    }
    
    public static byte[] getRequestPostBytes(HttpServletRequest request) throws Exception {
        int contentLength = request.getContentLength();
        if(contentLength<0){
            return null;
        }
        byte buffer[] = new byte[contentLength];
        for (int i = 0; i < contentLength;) {

            int readlen = request.getInputStream().read(buffer, i,
                    contentLength - i);
            if (readlen == -1) {
                break;
            }
            i += readlen;
        }
        return buffer;
    }
}
